﻿using System;
using System.Data;
using MySql.Data.MySqlClient;

namespace MySqlQueryToolkit.DataAccess
{
    public class MySqlDataAccess : IDataAccess
    {
        protected readonly MySqlCommand _command;
        protected readonly MySqlConnection Connection;

        public MySqlDataAccess(string connectionString)
        {
            Connection = new MySqlConnection(connectionString);
            _command = new MySqlCommand { Connection = Connection };
        }

        public bool CheckConnection()
        {
            try
            {
                using (Connection)
                {
                    Connection.Open();
                    return true;
                }
            }
            catch (Exception)
            {
                return false;
            }
        }

        public string CommandText
        {
            set { _command.CommandText = value; }
            get { return _command.CommandText; }
        }

        public void AddParameter<T>(string name, T value) where T : struct
        {
            IDbDataParameter param = _command.CreateParameter();
            param.ParameterName = name;
            param.Value = value;
            _command.Parameters.Add(param);
        }

        public IDataParameterCollection Parameters
        {
            get { return _command.Parameters; }
        }

        public long ExecuteTimedQuery()
        {
            var startTime = DateTime.Now;
            ExecuteNonQuery();
            var stopTime = DateTime.Now;
            var duration = stopTime - startTime;
            return duration.Milliseconds;
        }

        public virtual int ExecuteNonQuery()
        {
            try
            {
                using (Connection)
                {
                    Connection.Open();
                    return _command.ExecuteNonQuery();
                }
            }
            finally
            {
                _command.Parameters.Clear();
            }
        }

        public virtual void ExecuteReader(Action<IDataReader> dataMapperAction)
        {
            ExecuteReader(dataMapperAction, CommandBehavior.Default);
        }

        public virtual void ExecuteReader(Action<IDataReader> dataMapperAction, CommandBehavior behavior)
        {
            try
            {
                using (Connection)
                {
                    Connection.Open();
                    using (IDataReader reader = _command.ExecuteReader(behavior))
                    {
                        dataMapperAction(reader);
                    }
                }
            }
            finally
            {
                _command.Parameters.Clear();
            }
        }
    }
}
